#include "../logs/log.h"
#include <unistd.h>
enum class TimeGap
{
    GAP_SECOND,
    GAP_MINUTE,
    GAP_HOUR,
    GAP_DAY
};
// 进行扩展，一时间段来进行文件滚动
class RollByTimeSink : public logs::LogSink
{
public:
    RollByTimeSink(const std::string &base_name, TimeGap gap_type) : _file_name(base_name)
    {
        switch (gap_type)
        {
        case TimeGap::GAP_SECOND:
            _gap_size = 1;
            break;
        case TimeGap::GAP_MINUTE:
            _gap_size = 60;
            break;
        case TimeGap::GAP_HOUR:
            _gap_size = 3600;
            break;
        case TimeGap::GAP_DAY:
            _gap_size = 3600 * 24;
            break;
        }
        _cur_gap = logs::util::Data::getTime() / _gap_size;
        logs::util::File::createDirectory(logs::util::File::getPath(base_name));
        createNewFile();
    }
    void log(const char *data, size_t len)
    {
        // 判断是否在同一个时间段
        // 缺点就是，会创建多余文件；这样的问题也仅仅是在相对时间间隔较小的情况下出现，会多创建一个文件；（可忽略）
        // 调整：_cur_gap - logs::util::Data::getTime()计算第一次初始化创建文件到现在相差多少秒
        // 相差时间除以时间间隔，得到过了多少个时间间隔；
        if (logs::util::Data::getTime() / _gap_size != _cur_gap)
        {
            _ofs.close();
            createNewFile();
            _cur_gap = logs::util::Data::getTime() / _gap_size; // 注意更新时间间隔
        }
        _ofs.write(data, len);
        assert(_ofs.good());
    }

private:
    void createNewFile()
    {
        // 获取时间戳
        time_t t = logs::util::Data::getTime();
        std::stringstream file_name;
        struct tm lt;
        localtime_r(&t, &lt);
        file_name << _file_name;

        // a20041011132416.log
        file_name << lt.tm_year + 1900;
        file_name << lt.tm_mon + 1;
        file_name << lt.tm_mday;
        file_name << lt.tm_hour;
        file_name << lt.tm_min;
        file_name << lt.tm_sec;
        file_name << ".log";
        // 创建文件,自动生成扩展文件名
        // 格式：a.172334554.log
        _ofs.open(file_name.str(), std::ios::app | std::ios::binary);

        assert(_ofs.is_open());
    }

private:
    std::string _file_name;
    std::ofstream _ofs;
    size_t _cur_gap;  // 当前是在第几个时间段
    size_t _gap_size; // 时间段的大小
};

void test_log()
{
    DEBUG("%s", "测试开始！");

    // logs::logger::ptr logger = logs::LoggerManager::getInstance().get_Logger("async_logger");
    logs::logger::ptr logger = logs::getLogger("async_logger");
    logger->debug("%s", "异步日志器测试...");
    logger->info("%s", "异步日志器测试...");
    logger->warn("%s", "异步日志器测试...");
    logger->error("%s", "异步日志器测试...");
    logger->fatal("%s", "异步日志器测试...");
    size_t cnt = 0;
    while (cnt < 10000)
    {
        logger->fatal("%s - %d", "异步日志器测试...", cnt++);
        usleep(1000);
    }

    DEBUG("%s", "测试结束！");
}
int main()
{
    // 可自定义创建日志器，定义日志器的输出
    std::unique_ptr<logs::LoggerBuilder> builder = std::make_unique<logs::GlobalLoggerBuild>();
    builder->BuilderLoggerType(logs::LoggerType::LOGGER_ASYNC);
    builder->BuilderLoggerName("async_logger");
    builder->BuilderLoggerLevel(logs::LogLevel::Value::WARN);
    // builder->BuilderLoggerFormatter("%m%n");
    // builder->buildSink<logs::StdoutSink>();
    builder->buildSink<RollByTimeSink>("./aa/test-", TimeGap::GAP_SECOND);
    // builder->BuilderEnableUnsafeAsync();
    builder->build();

    logs::logger::ptr logger = logs::getLogger("async_logger");
    while (1)
    {
        logger->fatal("%s", "异步日志器测试...");
        sleep(2);
    }

    // test_log();
    return 0;
}